﻿using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet;
using MQTTnet.Protocol;
using Transponder_Core.DataSource;
using Transponder_Core.DataTarget;

namespace Transponder_WindownApp
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.btnCloseTarget.Enabled = false;
            this.btnPublish.Enabled = false;
        }
        /// <summary>
        /// 
        /// </summary>
        public MqttTarget mMqttTarget;

        public MqttSource mMqttSource;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnOpenSource_Click(object sender, EventArgs e)
        {

            var host = this.txtHostSource.Text.Trim();
            var port = (int)this.txtPortSource.Value;
            
            var userName = this.txtUserNameSource.Text.Trim();
            var password = this.txtPasswordSource.Text.Trim();
             
            if (string.IsNullOrWhiteSpace(host))
            {
                MessageBox.Show("host is null");
                return;
            }
            if (string.IsNullOrWhiteSpace(userName))
            {
                MessageBox.Show("userName is null");
                return;
            }
            if (string.IsNullOrWhiteSpace(password))
            {
                MessageBox.Show("password is null");
                return;
            }
 
            // 通过工厂创建MQTT客户端
            mMqttSource = new MqttSource();

            mMqttSource.Host = host;
            mMqttSource.Port = port;
            mMqttSource.UserName = userName;
            mMqttSource.Password = password;

            mMqttSource.Connected += MMqttClientSource_Connected;

            mMqttSource.Disconnected += MMqttClientSource_Disconnected;

            mMqttSource.EventReportReceived += MMqttClientSource_EventReportReceived;

            mMqttSource.RealTimeElectricalParametersReceived += MMqttClientSource_RealTimeElectricalParametersReceived;

           await mMqttSource.Open();
 

            this.btnOpenSource.Enabled = false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MMqttClientSource_Connected(object? sender, EventArgs e)
        {
            var eventReportTopic = this.txtEventReportTopic.Text.Trim();

            this.BeginInvoke(() =>
            {

                this.txtLog.AppendText("连接成功：" + System.Environment.NewLine);

                this.btnOpenSource.Enabled = false;
                this.btnCloseSource.Enabled = true;
                this.btnPublish.Enabled = true;

                this.txtHostSource.Enabled = false;
                this.txtPortSource.Enabled = false;
                this.txtUserNameSource.Enabled = false;
                this.txtPasswordSource.Enabled = false;
                this.txtEventReportTopic.Enabled = false;


            });
        }

        public void UpdateCount()
        {
            this.BeginInvoke(() => {

                this.lblSourceCount.Text = "接收数量：" + DataSourceCount;
                this.lblTargetCount.Text = "发送数量：" + DataTargetCount;

                if (this.txtBodySource.TextLength > 2000)
                {
                    this.txtBodySource.Clear();
                }
                if (this.txtBodyTarget.TextLength > 2000)
                {
                    this.txtBodyTarget.Clear();
                }
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private async void MMqttClientSource_RealTimeElectricalParametersReceived(object? sender, RealTimeElectricalParametersEventArgs e)
        {
            DataSourceCount += 1;

            UpdateCount();

            this.BeginInvoke(() => {

                this.txtBodySource.Text = e.Message.ToJson();
            
            });

            if (this.cbTran.Checked)
            {
                DataTargetCount += 1;
                var publishTopic = this.txtPublishTopicTarget.Text.Trim();
                var payload = e.Message.ToPayload();
                var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                // payload.devs
                payload.pKey = this.txtPKeyTarget.Text.Trim();

                foreach (var dev in payload.devs) {
                    dev.dev=this.txtDevIdTarget.Text.Trim();

                }

                var message = payload.ToJson();


                await this.PublishToTargetAsync(publishTopic, message);
            }

          
        }

        private async void MMqttClientSource_EventReportReceived(object? sender, EventReportEventArgs e)
        {
            DataSourceCount += 1;
            UpdateCount();

            this.BeginInvoke(() => {

                this.txtBodySource.Text = e.Message.ToJson();

            });

            if (this.cbTran.Checked)
            {
                DataTargetCount += 1;
                var publishTopic = this.txtPublishTopicTarget.Text.Trim();
                var payload = e.Message.ToPayload();
                var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                // payload.devs
                payload.pKey = this.txtPKeyTarget.Text.Trim();

                var message = payload.ToJson();

                await this.PublishToTargetAsync(publishTopic, message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void MMqttClientSource_Disconnected(object? sender, EventArgs e)
        {
            this.BeginInvoke(() =>
            {
                this.txtLog.AppendText("断开连接：" + System.Environment.NewLine);
                this.btnOpenSource.Enabled = true;
                this.btnCloseSource.Enabled = false;

                this.txtHostSource.Enabled = true;
                this.txtPortSource.Enabled = true;
                this.txtUserNameSource.Enabled = true;
                this.txtPasswordSource.Enabled = true;
                this.txtEventReportTopic.Enabled = true;

            });
           
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="publishTopic"></param>
        /// <param name="payload"></param>
        /// <returns></returns>
        public async Task PublishToTargetAsync(string publishTopic,string payload)
        {

            this.Invoke(() => {

                this.txtBodyTarget.Text = payload;
            });
            if (mMqttTarget != null && mMqttTarget.IsConnected)
            {
                await mMqttTarget.PublishAsync(publishTopic, payload);
            }
        }
        public int DataSourceCount = 0;

        public int DataTargetCount = 0;
 
       

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnOpenTarget_Click(object sender, EventArgs e)
        {
            var host = this.txtHostTarget.Text.Trim();
            var port = (int)this.txtPortTarget.Value;
            var clientId = Guid.NewGuid().ToString();
            var userName = this.txtUserNameTarget.Text.Trim();
            var password = this.txtPasswordTarget.Text.Trim();


            if (string.IsNullOrWhiteSpace(host))
            {
                MessageBox.Show("host is null");
                return;
            }
            if (string.IsNullOrWhiteSpace(userName))
            {
                MessageBox.Show("userName is null");
                return;
            }
            if (string.IsNullOrWhiteSpace(password))
            {
                MessageBox.Show("password is null");
                return;
            }
 

            // 通过工厂创建MQTT客户端
            mMqttTarget = new MqttTarget();
  
            mMqttTarget.Connected += MMqttTarget_Connected; ;

            mMqttTarget.Disconnected += MMqttTarget_Disconnected;

            
          await  mMqttTarget.Open();
          
            this.btnOpenTarget.Enabled = false;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void MMqttTarget_Connected(object? sender, EventArgs e)
        {
            this.BeginInvoke(() =>
            {

                this.txtLog.AppendText("连接成功：" + System.Environment.NewLine);

                this.btnOpenTarget.Enabled = false;
                this.btnCloseTarget.Enabled = true;
                this.btnPublish.Enabled = true;

                this.txtHostTarget.Enabled = false;
                this.txtPortTarget.Enabled = false;
                this.txtUserNameTarget.Enabled = false;
                this.txtPasswordTarget.Enabled = false;


            });
         
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void MMqttTarget_Disconnected(object? sender, EventArgs e)
        {
            this.BeginInvoke(() =>
            {
                this.txtLog.AppendText("断开连接：" + System.Environment.NewLine);
                this.btnOpenTarget.Enabled = true;
                this.btnCloseTarget.Enabled = false;
                this.btnPublish.Enabled = false;

                this.txtHostTarget.Enabled = true;
                this.txtUserNameTarget.Enabled = true;
                this.txtPasswordTarget.Enabled = true;

            });
        }
  

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnPublish_Click(object sender, EventArgs e)
        {
            var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var publishTopic = this.txtPublishTopicTarget.Text.Trim();
            var payload = new Payload();
            payload.pKey = this.txtPKeyTarget.Text.Trim();
            payload.ts = ts;

            var device = new Device();

            device.dev = this.txtDevIdTarget.Text.Trim();
            device.ts = ts;

            MeasurePoint measurePoint = new MeasurePoint();

            measurePoint.m = MeasurePointKeys.Ta.ToString();

            measurePoint.v = (decimal)Random.Shared.NextDouble();

            measurePoint.ts = ts;

            device.d.Add(measurePoint);

            payload.devs.Add(device);

            var json = System.Text.Json.JsonSerializer.Serialize(payload);

            this.txtBodyTarget.AppendText(json);
             
             await mMqttTarget.PublishAsync(publishTopic, json);
             
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnCloseTarget_Click(object sender, EventArgs e)
        {
            if (mMqttTarget != null && mMqttTarget.IsConnected)
            {
                await mMqttTarget.DisconnectAsync();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnCloseSource_Click(object sender, EventArgs e)
        {
            if (mMqttSource != null && mMqttSource.IsConnected)
            {
                await mMqttSource.DisconnectAsync();
            }
        }
    }
}
